import {
  RestFailedResponse,
  RestProvider,
  RestRequestData,
  RestRequestOptions,
  RestSuccessfulResponse,
} from '@discordoo/providers'
import { Client, CompletedRestOptions, DiscordooError } from 'discordoo'
import { RawFile, REST } from '@discordjs/rest'

/*
* replacement for https://docs.ddoo.dev/ref/discordoo/rest/DefaultRestProvider;
* default rest provider does not handle rate limits
*/
export class CustomRestProvider implements RestProvider {
  private rest: REST

  constructor(
    private discordoo: Client, private options: CompletedRestOptions,
  ) {
    this.rest = new REST().setToken(discordoo.token)
  }

  init(): Promise<unknown> {
    return Promise.resolve(undefined)
  }

  async request<T = any>(data: RestRequestData, options?: RestRequestOptions):
    Promise<RestSuccessfulResponse<T> | RestFailedResponse> {

    const before = Date.now()
    const response = await this.rest.raw({
      headers: {
        'User-Agent': this.options.userAgent,
      },
      method: data.method as any,
      fullRoute: `/${data.path}`,
      files: data.attachments.length ? data.attachments as RawFile[] : undefined,
      body: data.body,
      reason: options?.reason,
      auth: true,
    })
    const after = Date.now()

    let result: any = await response.body.text(),
      success = response.statusCode > 199 && response.statusCode < 400

    console.log('PROVIDER REQUEST EXECUTED, SUCCESS:', success, 'DATA:', response, 'BODY:', result)

    try {
      if (response.statusCode !== 204) result = JSON.parse(result)
    } catch (e) {
      success = false
      // TODO: rest failed response
      result = new DiscordooError('DefaultRestProvider#request', 'failed to parse response:', result)
    }

    return {
      statusCode: response.statusCode,
      result,
      headers: response.headers,
      success,
      latency: after - before,
    }
  }
}
